//###############
//FILE : FileRequestSession.java
//WRITER : Daniel Lowengrub, daniel_i_l, 320687098
//EXERCISE : oop ex3 2011
//DESCRIPTION:
//See below
//###############
package oop.ex3.protocol.sessions;

import oop.ex3.protocol.messages.WantFileMsg;
import oop.ex3.protocol.messages.FileNotFoundMsg;
import oop.ex3.protocol.messages.FileMsg;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import oop.ex3.exceptions.InvalidMessageException;
import oop.ex3.filemanager.FileDatabase;

/**
 * This is in charge of getting a want file request and sending the requested file if
 * it exists.
 * @author daniel
 */
public class FileRequestSession extends FileToFileSession {
    private String _fileName;
    private FileDatabase _fileDatabase;
    private DataInputStream _dataInput;

    /**
     * Create a new session.
     */
    public FileRequestSession() {
        super (new WantFileMsg());
    }

    /**
     * Set the file database that will be used for looking up a file and sending it.
     * @param fileDatabase The file database.
     */
    public void setFileDatabase(FileDatabase fileDatabase) {
        _fileDatabase = fileDatabase;
    }


    @Override
    protected boolean specExecuteSession(DataInputStream inputStream, DataOutputStream outputStream) throws IOException, InvalidMessageException {
        //first receive the want file request
        WantFileMsg wantFile = new WantFileMsg();
        wantFile.receive(inputStream);
        
        _fileName = wantFile.getFileName();
        
        //System.out.println("handleing want file: " + _fileName);
        if ((!_fileDatabase.hasFile(_fileName))
                || (!_fileDatabase.streamingPermission(_fileName))) {
            FileNotFoundMsg notFound = new FileNotFoundMsg();
            notFound.send(outputStream);
            return true; //finished successfully
        }

        //send the file
        FileInputStream fileIn = _fileDatabase.getFileStream(_fileName);
        BufferedInputStream buffIn = new BufferedInputStream(fileIn);
        _dataInput = new DataInputStream(buffIn);
        long fileLength = _fileDatabase.getFileLength(_fileName);

        _fileDatabase.addStream(_fileName);
        FileMsg fileMsg = new FileMsg();
        fileMsg.setFileInputStream(_dataInput);
        fileMsg.setInputLength(fileLength);

        fileMsg.send(outputStream);

        _dataInput.close();
        _fileDatabase.removeStream(_fileName);

        return true;
    }

    @Override
    protected void cleanup(DataOutputStream outputStream) {
        try {
            if (_dataInput != null)
                _dataInput.close();
        } catch (IOException ex) {
            //nothing to do
        }
        
        try {
            _errorMsg.send(outputStream);
        } catch (IOException ex) {
            ex.printStackTrace();
            //nothing left to do after sending error message
        }
    }

}
